package com.cloud.lan.entity.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.List;

public class ExcelUtil<T> {

    private static final Logger logger = LoggerFactory.getLogger(ExcelUtil.class);
    @SuppressWarnings("rawtypes")
    private static ExcelUtil excelUtil = new ExcelUtil();

    private ExcelUtil() {
    }

    @SuppressWarnings("rawtypes")
    public static ExcelUtil getExcelUtil() {
        return excelUtil;
    }

    /**
     *
     * @param titles
     *            校验excel文件格式的标题列内容
     * @param wb
     *            解析excel产生的workbook
     * @return
     */

//    public String checkExcelRules(String[] titles, Workbook wb,int batchCount) {
//        String result = null;
//
//        Sheet sheet = wb.getSheetAt(0);
//
//
//        if (sheet != null && sheet.getLastRowNum() > 0) {
//            if(sheet.getLastRowNum()>batchCount){
//                result = "单个文件只支持"+batchCount+"行数据";
//                return result;
//            }
//
//            Row firstRow = sheet.getRow(0);
//            if (firstRow == null) {
//                result = "第一行为空";
//                return result;
//            }
//
//            for (int ruleIndex = 0; ruleIndex < titles.length; ruleIndex++) {
//                String cellContent = getStringCellValue(firstRow.getCell(ruleIndex));
//                if(StringUtils.isBlank(cellContent)){
//                    result = "第一行第"+ruleIndex+"列为空";
//                    return result;
//                }
//                boolean condition = cellContent.trim().equals(titles[ruleIndex].trim());
//                if (!condition) {
//                    result = "Excel文件格式异常,出错列名称为：" + cellContent+",需为"+titles[ruleIndex].trim();
//                    return result;
//                }
//            }
//
//        } else{
//            result = "excel文件行数为0";
//        }
//
//
//        return result;
//    }

    /**
     *
     * @param wb
     * @param t
     *            excel记录的每条文本类型
     * @return excel包含的所有sheet记录
     */
//    public ArrayList<List<T>> getListFromExcel(XSSFWorkbook wb, Class<T> t) {
//        ArrayList<List<T>> totalSheets = new ArrayList<List<T>>();
//        if (wb != null && wb.getNumberOfSheets() > 0) {
//            mapperExcelToDomain(t, wb, totalSheets);
//        }
//        return totalSheets;
//    }



    /**
     * 将excel第一个sheet里的每一行build完添加到数组里
     * @param wb
     * @param t
     * @return
     */
//    public List<T> getRecordsFromExcel(XSSFWorkbook wb, Class<T> t) {
//
//        if (wb != null && wb.getNumberOfSheets() > 0) {
//            return mapperExcelToDomain(t, wb);
//        }
//        return null;
//    }




    /**
     * 将excel第一个sheet里的每一行build完添加到数组里
     * @return
     */
//    @SuppressWarnings("static-access")
//    private List<T> mapperExcelToDomain(Class<T> t, XSSFWorkbook wb) {
//
//        XSSFSheet sheet = wb.getSheetAt(0);
//
//        if (sheet != null && sheet.getLastRowNum() > 0) {
//            List<T> recordsList = new ArrayList<>(sheet.getLastRowNum());
//            XSSFRow firstRow = sheet.getRow(0);
//            if(firstRow!=null){
//                short cellNum = firstRow.getLastCellNum();
//
//                for (int i = 1; i <= sheet.getLastRowNum(); i++) {
//                    T me = null;
//                    try {
//                        me = t.newInstance();
//                    } catch (InstantiationException | IllegalAccessException e) {
//                        // TODO Auto-generated catch block
//                    }
//                    XSSFRow row = sheet.getRow(i);
//
//                    Field[] fields = t.getDeclaredFields();
//                    for (int filedIndex = 0; filedIndex < cellNum; filedIndex++) {
//                        XSSFCell cell = row.getCell(filedIndex);
//                        String msg = getStringCellValue(cell);
//                        try {
//                            Field temp = fields[filedIndex];
//                            temp.setAccessible(fields, true);
//                            temp.set(me, msg);
//                        } catch (Exception e) {
//                        }
//                    }
//                    recordsList.add(me);
//                }
//            }
//            return recordsList;
//
//        }
//        return null;
//
//    }


    @SuppressWarnings("static-access")
//    private void mapperExcelToDomain(Class<T> t, XSSFWorkbook wb, ArrayList<List<T>> totalSheets) {
//        for (int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
//            XSSFSheet sheet = wb.getSheetAt(sheetNum);
//            if (sheet != null && sheet.getLastRowNum() > 0) {
//                List<T> recordsList = new ArrayList<>(sheet.getLastRowNum());
//                for (int i = 1; i <= sheet.getLastRowNum(); i++) {
//                    T tempRecords = null;
//                    try {
//                        tempRecords = t.newInstance();
//                    } catch (InstantiationException | IllegalAccessException e) {
//                        // TODO Auto-generated catch block
//                    }
//                    XSSFRow row = sheet.getRow(i);
//                    Field[] fields = t.getDeclaredFields();
//                    for (int filedIndex = 0; filedIndex < fields.length; filedIndex++) {
//                        XSSFCell cell = row.getCell(filedIndex);
//                        String msg = getStringCellValue(cell);
//                        try {
//                            Field temp = fields[filedIndex];
//                            temp.setAccessible(fields, true);
//                            temp.set(tempRecords, msg);
//                        } catch (IllegalArgumentException e) {
//                        } catch (IllegalAccessException e) {
//                        }
//                    }
//                    recordsList.add(tempRecords);
//                }
//                totalSheets.add(recordsList);
//            }
//        }
//    }

//    public String getStringCellValue(Cell cell) {
//        String s = null;
//        if (cell != null) {
//            switch (cell.getCellType()) {
//                case STRING:
//                    s = cell.getStringCellValue();
//                    if (StringUtils.isNotBlank(s)) {
//                        s = s.trim();
//                    }
//                    break;
//                case NUMERIC:
//
//                    s = new HSSFDataFormatter().formatCellValue(cell);
//                    if (StringUtils.isNotBlank(s)) {
//                        s = s.trim();
//                    }
//                    break;
//
//                case FORMULA:
//
//                    s = String.valueOf(cell.getNumericCellValue());
//                    if (StringUtils.isNotBlank(s)) {
//                        s = s.trim();
//                    }
//
//                    break;
//
//
//                default:
//                    break;
//            }
//        }
//        return s;
//    }

    /**
     *
     * @param excelDesPath
     *            创建的excel的文件地址
     * @param title
     *            创建的excel的文件标题
     * @param list
     *            数据库查询出的数据
     * @return 生成excel到磁盘
     */
    public String createExcelFromList(String excelDesPath, String[] title, List<T> list) {
        String createFile = "success";
        try {
            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet sheet = wb.createSheet("批量结果");
            if (title != null && title.length > 0 && list != null && list.size() > 0) {
                wirteHead(title, sheet);

                writeContent(list, sheet);
                try {
                    FileOutputStream fout = new FileOutputStream(excelDesPath);
                    wb.write(fout);
                    fout.close();
                } catch (Exception e) {
                    logger.error("创建excel失败",e);
                    createFile = "failed";
                }
            }
        } catch (Exception e) {
            logger.error("创建excel失败2",e);
            createFile = "failed";
        }
        return createFile;
    }

    public byte[] createExcelFromList(String[] title, List<T> list) {
        try {
            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet sheet = wb.createSheet("批量结果");
            if (title != null && title.length > 0 && list != null && list.size() > 0) {
                wirteHead(title, sheet);

                writeContent(list, sheet);
                try (ByteArrayOutputStream bout = new ByteArrayOutputStream()) {
                    wb.write(bout);
                    return bout.toByteArray();
                } catch (Exception e) {
                    logger.error("写入excel失败", e);
                    return null;
                }
            }
        } catch (Exception e) {
            logger.error("创建excel失败",e);
            return null;
        }
        return null;
    }

    private void writeContent(List<T> list, XSSFSheet sheet) {
        XSSFRow row;
        for (int records = 0; records < list.size(); records++) {
            row = sheet.createRow(records + 1);
            T tempRecords = list.get(records);
            if(tempRecords==null){
                logger.error("获取第{}条数据为空",records);
                return ;
            }
            Field[] fields = tempRecords.getClass().getDeclaredFields();

            for (int filedIndex = 0; filedIndex < fields.length; filedIndex++) {
                XSSFCell cell = row.createCell(filedIndex);
                try {
                    Field temp = fields[filedIndex];
                    if (temp.isSynthetic()) {
                        continue;
                    }
                    temp.setAccessible(fields, true);
                    Object cellValue = temp.get(tempRecords);
                    logger.info("field:{},value:{}", temp.getName(), cellValue);
                    if(cellValue!=null && StringUtils.isNotBlank(cellValue.toString())){
                        cell.setCellValue(cellValue.toString());
                    } else{
                        cell.setCellValue("");
                    }

                } catch (Exception e) {
                    logger.error("write content error",e);
                    cell.setCellValue("该记录数据不合法，请重新操作");
                }
            }
        }
    }

    private void wirteHead(String[] title, XSSFSheet sheet) {
        XSSFRow row = sheet.createRow(0);
        for (int headIndex = 0; headIndex < title.length; headIndex++) {
            XSSFCell cell = row.createCell(headIndex);
            cell.setCellValue(title[headIndex]);

        }
    }

    /**
     *
     * @author chad.chen
     *            List存放对象数据(listData)
     */
//    public ByteArrayOutputStream objListToXlsxInMemory(Map data) {
//        ByteArrayOutputStream baos = null;
//        Map<String, String> columns = (Map<String, String>) data.get("columns");
//        List listData = (List) data.get("listData");
//        Object[] keys = columns.keySet().toArray();
//        String[] ziDuanKeys = new String[keys.length];
//        for (int k = 0; k < keys.length; k++) {
//            String temp = keys[k].toString();
//            String str = temp.substring(0, 2);
//            Pattern p = Pattern.compile("\\d(\\d)?");
//            Matcher m = p.matcher(str);
//            if (m.matches()) {
//                int xuHao = Integer.valueOf(temp.substring(0, 2));
//                ziDuanKeys[xuHao] = temp.substring(2);
//            } else {
//                int xuHao = Integer.valueOf(temp.substring(0, 1));
//                ziDuanKeys[xuHao] = temp.substring(1);
//            }
//        }
//        try {
//            SXSSFWorkbook wb = new SXSSFWorkbook(1000);
//            SXSSFSheet sheet = wb.createSheet();
//            for (int i = 0; i < listData.size() + 1; i++) {
//                SXSSFRow row = sheet.createRow(i);
//                for (int j = 0; j < ziDuanKeys.length; j++) {
//                    SXSSFCell cell = row.createCell(j);
//                    if (i == 0) {
//                        sheet.setColumnWidth(j, 6000);
//                        cell.setCellValue(columns.get(j + ziDuanKeys[j]));
//                    } else {
//                        Object obj = listData.get(i - 1);
//                        String ziDuanName = (String) ziDuanKeys[j];
//                        ziDuanName = ziDuanName.replaceFirst(ziDuanName.substring(0, 1),
//                                ziDuanName.substring(0, 1).toUpperCase());
//                        ziDuanName=getZiduanName(ziDuanName);
//                        Class clazz = Class.forName(obj.getClass().getName());
//                        Method[] methods = clazz.getMethods();
//                        Pattern pattern = Pattern.compile(ziDuanName);
//                        Matcher mat = null;
//                        for (Method m : methods) {
//                            mat = pattern.matcher(m.getName());
//                            if (mat.find()) {
//                                Object shuXing = m.invoke(obj, null);
//                                if (shuXing != null) {
//                                    cell.setCellValue(shuXing.toString());// 这里可以做数据格式处理
//                                } else {
//                                    cell.setCellValue("");
//                                }
//                                break;
//                            }
//                        }
//                    }
//                }
//            }
//            baos = new ByteArrayOutputStream();
//            wb.write(baos);// 写入File
//            wb.close();
//            return baos;
//        } catch (Exception e) {
//            logger.error(e.getMessage());
//            return null;
//        }
//    }

    public String getZiduanName(String ziDuanName){
        StringBuilder sb=new StringBuilder();
        sb.append("get").append(ziDuanName);
        return sb.toString();
    }



}
